#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
@date: 2011-11-06
@author: shell.xu
'''
import os, sys, hashlib, string
import web
import tmpl
import pymongo
from bson.binary import Binary
from utils import *

users = web.config.db['user']

form_login = form.Form(
    form.Textbox('username', description = 'username'),
    form.Password('password', description = 'password'),
    form.Button("submit", type="submit", description="Submit"),
    )

class login(object):
    ''' 登录 '''
    def GET(self):
        if web.config.sess.get('user', None) is not None:
            return web.seeother(web.config.urls.get('login_redir', '/'))
        return calltmpl(tmpl.user.login, form = form_login())

    def POST(self):
        if web.config.sess.get('user', None) is not None:
            return web.seeother(web.config.urls.get('login_redir', '/'))
        f = form_login()
        if not f.validates(): return calltmpl(tmpl.user.login, form = f)
        user = users.find_one({'_id': f.username.get_value()})
        hashpass = hashlib.md5(f.password.get_value()).digest()
        if user is None or str(user['password']) != hashpass:
            return calltmpl(tmpl.user.login, form = f, info = 'login failed')
        web.config.sess.user = user
        return web.seeother(web.config.urls.get('login_redir', '/'))

class logout(object):
    ''' 登出 '''
    def GET(self):
        web.config.sess.user = None
        return web.seeother('./login')
    POST = GET

# 检测是否是合法的用户名
charlist = set(string.digits + string.letters + '@.')
def check_username(x):
    return all(map(lambda i: i in charlist, x))

form_register = form.Form(
    form.Textbox('username',
                 form.Validator('illegal username', check_username),
                 description = 'username'),
    form.Textbox('email', description = 'email'),
    form.Textbox('website', description = 'website'),
    form.Password('password1', description = 'password'),
    form.Password('password2', description = 're-type password'),
    form.Button("submit", type="submit", description="Submit"),
    validators = [
        form.Validator("Passwords did't match", lambda i: i.password1 == i.password2)]
    )
# website和email也应当进行检测

class register(object):
    ''' 注册 '''
    def GET(self):
        if web.config.sess.get('user', None) is not None:
            return web.seeother(web.config.urls['login_redir'])
        return calltmpl(tmpl.user.register, form = form_register())

    def POST(self):
        f = form_register()
        if not f.validates(): return calltmpl(tmpl.user.register, form = f)
        user = users.find_one({'_id': f.username.get_value()})
        hashpass = hashlib.md5(f.password1.get_value()).digest()
        if user is not None:
            return calltmpl(tmpl.user.register, form = f, info = 'user exists')
        usr = form2obj(f, ['email', 'website'],
                       {'_id': f.username.get_value(), 'password': Binary(hashpass)})
        users.insert(usr, safe = True)
        return web.seeother(web.config.urls['user_login'])

class user_list(object):
    ''' 列出所有用户 '''
    def GET(self):
        return calltmpl(tmpl.user.list, userlist = users.find())

class show(object):
    ''' 显示某个用户的信息 '''
    # 这个基本没用
    def GET(self, username):
        user = users.find_one({'_id': username})
        if user is None: return 'user not exist'
        return calltmpl(tmpl.user.show, user = user)

class main(object):
    ''' 用户的主页 '''
    # 注意到这个action其实依赖了articles模块，因此不具备可移植性
    def GET(self):
        if web.config.sess.get('user', None) is None:
            return web.seeother(web.config.urls['user_login'])
        articles = web.config.db['articles']
        artlist = articles.find({'author': web.config.sess.user['_id']})
        artlist = artlist.sort('ctime', pymongo.DESCENDING).limit(5)
        return calltmpl(tmpl.user.main, user = web.config.sess['user'],
                        articles = artlist)
